package xyz.erupt.upms.model;

import com.shop.loan.model.Channel;
import com.shop.loan.model.Channel;
import lombok.Getter;
import lombok.Setter;
import org.hibernate.annotations.SQLDelete;
import xyz.erupt.annotation.Erupt;
import xyz.erupt.annotation.EruptField;
import xyz.erupt.annotation.EruptI18n;
import xyz.erupt.annotation.constant.AnnotationConst;
import xyz.erupt.annotation.expr.ExprBool;
import xyz.erupt.annotation.fun.FilterHandler;
import xyz.erupt.annotation.sub_erupt.Filter;
import xyz.erupt.annotation.sub_erupt.RowOperation;
import xyz.erupt.annotation.sub_erupt.Tpl;
import xyz.erupt.annotation.sub_field.*;
import xyz.erupt.annotation.sub_field.sub_edit.*;
import xyz.erupt.core.constant.MenuTypeEnum;
import xyz.erupt.core.constant.RegexConst;
import xyz.erupt.upms.handler.ViaMenuValueCtrl;
import xyz.erupt.upms.looker.LookerSelf;
import xyz.erupt.upms.model.input.ResetPassword;
import xyz.erupt.upms.model.input.ResetPasswordExec;

import javax.persistence.*;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Set;

/**
 * @author YuePeng
 * date 2018-11-22.
 */
@Entity
@Table(name = "e_upms_user", uniqueConstraints = {
        @UniqueConstraint(columnNames = "account")
})
@Erupt(
        name = "管理员",
        dataProxy = EruptUserDataProxy.class,
        filter = @Filter("EruptUser.isDelete = false"),
        rowOperation = {
                @RowOperation(title = "重置密码",
                        icon = "fa fa-refresh",
                        mode = RowOperation.Mode.SINGLE,
                        eruptClass = ResetPassword.class,
                        operationHandler = ResetPasswordExec.class)
        }
)
@SQLDelete(sql = "update e_upms_user set is_delete = true, delete_time = now() where id = ?")
@EruptI18n
@Getter
@Setter
public class EruptUser extends LookerSelf implements FilterHandler {

    @Column(length = AnnotationConst.CODE_LENGTH)
    @EruptField(
            views = @View(title = "登录账号", sortable = true),
            edit = @Edit(title = "登录账号", desc = "登录账号", notNull = true, search = @Search(vague = true))
    )
    private String account;

    @EruptField(
            views = @View(title = "姓名", sortable = true),
            edit = @Edit(title = "姓名", notNull = true, search = @Search(vague = true))
    )
    private String name;

    @EruptField(
            views = @View(title = "账户状态", sortable = true),
            edit = @Edit(
                    title = "账户状态",
                    search = @Search,
                    type = EditType.BOOLEAN,
                    notNull = true,
                    boolType = @BoolType(
                            trueText = "激活",
                            falseText = "锁定"
                    )
            )
    )
    private Boolean status = true;

    @EruptField(
            views = @View(title = "手机号码"),
            edit = @Edit(title = "手机号码",
                    search = @Search(vague = true),
                    notNull = true,
                    inputType = @InputType(regex = RegexConst.PHONE_REGEX))
    )
    private String phone;

    @EruptField(
            edit = @Edit(title = "邮箱", show = false, search = @Search(vague = true), inputType = @InputType(regex = RegexConst.EMAIL_REGEX))
    )
    private String email;

    @EruptField(
            views = @View(title = "超管用户", sortable = true),
            edit = @Edit(
                    title = "超管用户", notNull = true, search = @Search(vague = true)
            )
    )
    private Boolean isAdmin = false;

    @ManyToOne
    @EruptField(
            views = @View(title = "首页菜单", column = "name"),
            edit = @Edit(
                    title = "首页菜单",
                    type = EditType.REFERENCE_TREE,
                    referenceTreeType = @ReferenceTreeType(pid = "parentMenu.id"),
                    filter = @Filter(conditionHandler = EruptUser.class)
            )
    )
    private EruptMenu eruptMenu;

    @ManyToOne
    @EruptField(
            views = @View(title = "所属组织", column = "name", show = false),
            edit = @Edit(title = "所属组织", type = EditType.REFERENCE_TREE,
                    referenceTreeType = @ReferenceTreeType(pid = "parentOrg.id"),
                    show = false
            )
    )
    private EruptOrg eruptOrg;

    @ManyToOne
    @EruptField(
            views = @View(title = "岗位", column = "name", show = false),
            edit = @Edit(title = "岗位", type = EditType.REFERENCE_TREE, search = @Search, show = false)
    )
    private EruptPost eruptPost;


    private Long channelId;


    @EruptField(
            views = @View(title = "客服二维码", type = ViewType.IMAGE),
            edit = @Edit(title = "客服二维码",
                    type = EditType.ATTACHMENT,
                    attachmentType = @AttachmentType(
                            type = AttachmentType.Type.IMAGE))
    )
    private String serviceQrCode;


    @Transient
    @EruptField(
            edit = @Edit(title = "密码", type = EditType.DIVIDE)
    )
    private String pwdDivide;

    private String password;

    @Transient
    @EruptField(
            edit = @Edit(
                    title = "密码",
                    readonly = @Readonly(add = false),
                    desc = "8-16位字符，字母数字结合",
                    placeHolder = "8-16位字母数字结合的密码",
                    inputType = @InputType(regex = "^(?!^\\d+$)[a-zA-Z\\d\\W]{8,16}$")
            )
    )
    private String passwordA;

    @Transient
    @EruptField(
            edit = @Edit(title = "确认密码", readonly = @Readonly(add = false))
    )
    private String passwordB;

    //放款密码
    private String loanPassword;
    //还款密码
    private String payPassword;


    @ManyToMany(fetch = FetchType.EAGER)
    @JoinTable(
            name = "e_upms_user_role",
            joinColumns = @JoinColumn(name = "user_id", referencedColumnName = "id"),
            inverseJoinColumns = @JoinColumn(name = "role_id", referencedColumnName = "id")
    )
    @EruptField(
            views = @View(title = "所属角色"),
            edit = @Edit(
                    title = "所属角色",
                    type = EditType.CHECKBOX
            )
    )
    private Set<EruptRole> roles;


    @ManyToMany(
            fetch = FetchType.EAGER
    )
    @JoinTable(
            name = "s_erupt_user_channel",
            joinColumns = {@JoinColumn(
                    name = "erupt_user_id",
                    referencedColumnName = "id"
            )},
            inverseJoinColumns = {@JoinColumn(
                    name = "channel_id",
                    referencedColumnName = "id"
            )}
    )
    @OrderBy
    @EruptField(
            views = {@View(
                    title = "关联渠道"
            )},
            edit = @Edit(
                    title = "关联渠道",
                    type = EditType.CHECKBOX,
                    desc = "角色为渠道时设置"
            )
    )
    private Set<Channel> channelLinks;

    @EruptField(
            edit = @Edit(title = "固定验证码", placeHolder = "仅对渠道生效")
    )
    private String msgCode;

    @EruptField(
            views = @View(title = "重置密码时间", width = "130px", sortable = true)
    )
    private Date resetPwdTime;

    @EruptField(
            edit = @Edit(
                    title = "md5加密", type = EditType.BOOLEAN, notNull = true,
                    readonly = @Readonly(add = false),
                    show = false,
                    boolType = @BoolType(
                            trueText = "加密",
                            falseText = "不加密"
                    )
            )
    )
    private Boolean isMd5 = true;

    @EruptField(
            views = @View(title = "失效时间", sortable = true),
            edit = @Edit(title = "账号失效时间")
    )
    private Date expireDate;


    @Column(length = AnnotationConst.REMARK_LENGTH)
    @EruptField(
            edit = @Edit(
                    title = "ip白名单",
                    desc = "ip与ip之间使用换行符间隔，不填表示不鉴权",
                    type = EditType.TEXTAREA
            )

    )
    private String whiteIp;

    @Column(length = AnnotationConst.REMARK_LENGTH)
    @EruptField(
            edit = @Edit(
                    title = "备注",
                    type = EditType.TEXTAREA
            )
    )
    private String remark;


    private Boolean isDelete = false;

    private Date deleteTime;

    public EruptUser() {
    }

    public EruptUser(Long id) {
        this.setId(id);
    }

    @Override
    public String filter(String condition, String[] params) {
        List<String> nts = new ArrayList<>();
        nts.add(MenuTypeEnum.API.getCode());
        nts.add(MenuTypeEnum.BUTTON.getCode());
        return String.format("EruptMenu.type not in ('%s') or EruptMenu.type is null", String.join("','", nts));
    }

}
